﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace WpfComm.Servise
{
    public class SerialServer
    {
        #region 初始化
        /// <summary>
        /// 构造函数
        /// </summary>
        public SerialServer()
        {

        }
        public SerialServer(SerialPort slPort)
        {
            serialPort = slPort;
        }

        private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            /**
             TXFull 应用程序尝试传输一个字符，但是输出缓冲区已满。 
             RXOver 发生输入缓冲区溢出。 输入缓冲区空间不足，或在文件尾 (EOF) 字符之后接收到字符。 
             Overrun 发生字符缓冲区溢出。 下一个字符将丢失。 
             RXParity 硬件检测到奇偶校验错误。 
             Frame 硬件检测到一个组帧错误。 
             */
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (sava_Ok == false)
            {
                //一帧没有接收完成
                timerSave = new Timer(GetTimerInterval()); //两次 Elapsed 事件之间的时间（以毫秒为单位）。 该值必须大于零并小于或等于 Int32.MaxValue。默认值为 100 毫秒。 
                                                           //波特率9600，
                                                           //传送1个字节数据，有1位起始位，8位数据位、1位校验位、1位停止位，
                                                           //也就是说传一个字节要用11位的时间，每位1/9600秒，共用11/9600＝0.001 146秒。
                timerSave.AutoReset = false;
                timerSave.Elapsed += TimerSave_Elapsed;
                timerSave.Start();                                    

                SerialPort sp = (SerialPort)sender;
                string indata = sp.ReadExisting();
                serialSaveString += indata;

                Console.WriteLine("\nData Received:");
                Console.Write(indata);
            }
        }

        private void TimerSave_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (sava_Ok == false)
            {
                sava_Ok = true;
                //一帧已经接收完成-处理数据
                Console.WriteLine("接收完成");
                sava_Ok = false;

            }

        }


        #endregion
        #region 数据
        //串口
        private SerialPort serialPort = new SerialPort();
        //寄存器转码结构
        [StructLayout(LayoutKind.Explicit)]
        public struct TBytes
        {
            [FieldOffset(0)]
            public byte Byte0;

            [FieldOffset(1)]
            public byte Byte1;

            [FieldOffset(2)]
            public byte Byte2;

            [FieldOffset(3)]
            public byte Byte3;

            [FieldOffset(0)]
            public uint Word;
        }
        //接收完成标志
        private Boolean sava_Ok = false;
        //接收完整定时器
        private Timer timerSave;
        private string serialSaveString = "";
        #endregion

        #region 内部函数
        private double GetTimerInterval() {
            return 1;
        }
        #endregion

        #region 服务
        /// <summary>
        /// 打开串口
        /// </summary>
        public void SerialOpen() {
            if (serialPort == null) return;
            try
            {
                serialPort.Open();
                serialPort.DataReceived += SerialPort_DataReceived;
                serialPort.ErrorReceived += SerialPort_ErrorReceived;
                
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.ToString());
                System.Windows.MessageBox.Show("串口 {serialPort.PortName} 打开失败");
            }
            //Console.WriteLine("Press any key to continue...");
            //Console.WriteLine();
            //Console.ReadKey();
            //serialPort.Close();
        }
        /// <summary>
        /// 关闭串口
        /// </summary>
        public void SerialClose()
        {
            if (serialPort.IsOpen == true) serialPort.Close();
        }
        /// <summary>
        /// 串口异常处理
        /// </summary>
        public void SerialErrorhandling()
        {
        }

        #endregion
    }
}
